using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using JGSY.CMS.LowCode.Platform.Application.Interfaces;
using JGSY.CMS.LowCode.Platform.Infrastructure.Configuration;

namespace JGSY.CMS.LowCode.Platform.Infrastructure.Configuration.Extensions
{
    /// <summary>
    /// 权限路由映射热更新扩展
    /// 提供运行时配置更新和缓存刷新功能
    /// </summary>
    public static class PermissionRouteMappingExtensions
    {
        /// <summary>
        /// 配置权限路由映射热更新支持
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="enableDatabaseRouting">是否启用数据库路由映射</param>
        /// <param name="enableConfigRouting">是否启用配置文件路由映射</param>
        /// <returns>配置后的服务集合</returns>
        public static IServiceCollection AddPermissionRouteMappingSupport(
            this IServiceCollection services,
            bool enableDatabaseRouting = true,
            bool enableConfigRouting = true)
        {
            // 配置权限映射选项
            services.Configure<PermissionMappingOptions>(options =>
            {
                options.EnableDatabaseRouteMapping = enableDatabaseRouting;
                options.EnableConfigurationRouteMapping = enableConfigRouting;
                options.CacheExpirationMinutes = 30;
                options.RefreshIntervalMinutes = 5;
            });

            return services;
        }

        /// <summary>
        /// 启用权限路由映射中间件
        /// </summary>
        /// <param name="app">应用程序构建器</param>
        /// <returns>配置后的应用程序构建器</returns>
        public static IApplicationBuilder UsePermissionRouteMapping(this IApplicationBuilder app)
        {
            // 在应用程序启动时初始化缓存
            using (var scope = app.ApplicationServices.CreateScope())
            {
                var logger = scope.ServiceProvider.GetRequiredService<ILogger<IApplicationBuilder>>();
                var mappingService = scope.ServiceProvider.GetService<IPermissionRouteMappingService>();
                
                if (mappingService != null)
                {
                    try
                    {
                        // 预热缓存
                        _ = mappingService.GetActiveAsync().GetAwaiter().GetResult();
                        logger.LogInformation("Permission route mapping cache pre-warmed successfully");
                    }
                    catch (Exception ex)
                    {
                        logger.LogWarning(ex, "Failed to pre-warm permission route mapping cache");
                    }
                }
            }

            return app;
        }

        /// <summary>
        /// 触发权限路由映射缓存刷新
        /// </summary>
        /// <param name="serviceProvider">服务提供程序</param>
        /// <returns>是否刷新成功</returns>
        public static async Task<bool> RefreshPermissionRouteMappingCacheAsync(this IServiceProvider serviceProvider)
        {
            var mappingService = serviceProvider.GetService<IPermissionRouteMappingService>();
            if (mappingService == null) return false;

            var logger = serviceProvider.GetService<ILogger<IServiceProvider>>();
            
            try
            {
                await mappingService.RefreshCacheAsync();
                logger?.LogInformation("Permission route mapping cache refreshed manually");
                return true;
            }
            catch (Exception ex)
            {
                logger?.LogError(ex, "Failed to refresh permission route mapping cache");
                return false;
            }
        }
    }

    /// <summary>
    /// 权限映射配置选项
    /// </summary>
    public class PermissionMappingOptions
    {
        /// <summary>
        /// 是否启用数据库路由映射
        /// </summary>
        public bool EnableDatabaseRouteMapping { get; set; } = true;

        /// <summary>
        /// 是否启用配置文件路由映射
        /// </summary>
        public bool EnableConfigurationRouteMapping { get; set; } = true;

        /// <summary>
        /// 缓存过期时间（分钟）
        /// </summary>
        public int CacheExpirationMinutes { get; set; } = 30;

        /// <summary>
        /// 自动刷新间隔（分钟）
        /// </summary>
        public int RefreshIntervalMinutes { get; set; } = 5;

        /// <summary>
        /// 是否在应用启动时从配置导入路由映射
        /// </summary>
        public bool ImportConfigurationOnStartup { get; set; } = false;

        /// <summary>
        /// 导入时是否替换现有映射
        /// </summary>
        public bool ReplaceExistingOnImport { get; set; } = false;
    }
}
